#pragma once


#include <iostream>
#include <string>
#include <vector>
#include <bitset>


// BKDR Hash Function
struct HashFuncBKDR
{
    size_t operator()(const std::string& str)
    {
        size_t hash = 0;
        for (auto& c : str)
        {
            hash *= 31;
            hash += c;
        }
        return hash;
    }
};


// AP Hash Function
struct HashFuncAP
{
    size_t operator()(const std::string& str)
    {
        size_t hash = 0;
        for (size_t i = 0; i < str.size(); i++)
        {
            if ((i & 1) == 0)
            {
                hash ^= ((hash << 7) ^ str[i] ^ (hash >> 3));
            }
            else
            {
                hash ^= (~((hash << 11) ^ str[i] ^ (hash >> 5)));
            }
        }
        return hash;
    }
};


// DJB Hash Function
struct HashFuncDJB
{
    size_t operator()(const std::string& str)
    {
        size_t hash = 5381;
        for (auto& c : str)
            hash = hash * 33 ^ c;
        return hash;
    }
};